package vistaprincipal;

import java.util.List;
import java.util.ArrayList;

public class Expresion {
    List<String> ante;
    List<String> conse;
    int regla;
    int posicion;
    private int nega;
    int renglon, renglonPadre;
    
//constructor
    public Expresion(int renglonPadre, int renglon,List<String> ante,List<String> conse){
        this.ante=new ArrayList();
        this.conse=new ArrayList();
        this.renglonPadre=renglonPadre;
        this.renglon=renglon;
        this.ante.addAll(ante);
        this.conse=(List<String>)((ArrayList)conse).clone();
    }
    public boolean es_axioma (){
        int aux1=compara(ante);
        int aux2=-1;
        
        
        boolean axioma=false;
        //comparando si ya no tiene 
        if (aux1==-1){
            aux2=compara(conse);
            if(aux2==-1){
                axioma = true;
            }
            else{
                regla=6+aux2;
                return false;
            }
        }
        else{
            regla=1+aux1;
            return false;
        }           
        //comparando que se repita por lo menos una atómica
        for (int i=0;i<ante.size();i++){
            for (int j=0;j<conse.size();j++){
                if(ante.get(i).equals(",") || ante.get(i).equals(" ") || ante.get(i).equals(")") || ante.get(i).equals("("))break;
                if (ante.get(i).equals(conse.get(j)) && axioma==true){
                    return true;
                }
            }
        }
        return false;
    }
    
    private int compara(List<String> cadena){
        for (int i=0;i<cadena.size();i++){
             int x=cadena.get(i).codePointAt(0);    //cambia el caracter a codigo utf-8
             nega=0;
             posicion=i;
             switch (x){
                 case 55://7
                     if(i+2>=cadena.size()) //si se sale de la cadena
                        return 0;
                     x=cadena.get(i+2).codePointAt(0);
                     nega=1;
                     posicion=i+2;
                     if(x==8744) return 2;
                     if(x==8743) return 1; 
                     if(x==8594) return 3; 
                     if(x==8660) return 4;
                     posicion=i;
                     return 0;

                 case 8743://∧
                     return 1;
                 case 8744://∨
                     return 2;
                 case 8594://→
                     return 3;
                 case 8660://⇔
                     return 4;

                 default:
                 break;
             }//cierra switch  
        }//termina for
        return -1;  //no tiene mas simbolos
    }
    
    public List<Expresion> aplica_regla(List<Expresion> reservados){
        String aux="";
         Expresion exp = new Expresion(renglonPadre,renglon+1,(ArrayList)ante,(ArrayList)conse);
         //exp.ante=ante;
         //exp.conse=conse;
         exp.nega=nega;
         exp.posicion=posicion;
         exp.regla=regla;
          switch (regla){
                     case 1:// 7 =>
                         aux=ante.get(posicion+1);
                         ante.set(posicion," ");
                         ante.set(posicion+1," ");
                         conse.add(",");
                         conse.add(aux);
                     break;
                     case 2:// ^ =>
                         ante.set(posicion,",");
                     break;
                     case 3:// v =>
                         ante.set(posicion," ");
                         if("7".equals(ante.get(posicion+1))){
                             ante.set(posicion+1," ");
                             ante.set(posicion+2," ");
                         }
                         else
                             ante.set(posicion+1," ");
                         exp.ante.set(exp.posicion," ");
                         exp.ante.set(exp.posicion-1," ");
                             if (exp.nega==1){
                             exp.ante.set(exp.posicion-2," ");
                             }
                         reservados.add(exp);
                     break;
                     case 4:// -> =>
                         aux=ante.get(posicion-1);
                         ante.set(posicion," ");
                         ante.set(posicion-1," ");
                         if (nega==1){
                            ante.set(posicion-2," ");
                         }
                         exp.ante.set(exp.posicion," ");
                         exp.ante.set(exp.posicion-1," ");
                         if (exp.nega==1){
                            exp.ante.set(exp.posicion-2," ");
                         }                         
                         if("7".equals(exp.ante.get(exp.posicion+1))){
                             exp.ante.set(exp.posicion+1," ");
                             exp.ante.set(exp.posicion+2," ");
                         }
                         else
                             exp.ante.set(exp.posicion+1," ");
                         exp.conse.add(",");
                         if (exp.nega==1){
                            exp.conse.add("7");
                         }
                         exp.conse.add(aux);
                         reservados.add(exp);
                     break;
                     case 5:// <=> =>
                         ante.set(posicion,",");
                         exp.conse.add(",");
                         if (exp.nega==1){
                             exp.conse.add(exp.ante.get(exp.posicion-2));
                             exp.ante.set(exp.posicion-2," ");
                         }
                         
                         exp.conse.add(exp.ante.get(exp.posicion-1));
                         exp.ante.set(exp.posicion-1," ");
                         exp.conse.add(",");
                         exp.ante.set(exp.posicion," ");
                         exp.conse.add(exp.ante.get(exp.posicion+1));
                         if("7".equals(exp.ante.get(exp.posicion+1))){
                            exp.conse.add(exp.ante.get(exp.posicion+2));
                            exp.ante.set(exp.posicion+2," ");
                         }
                         exp.ante.set(exp.posicion+1," ");
                         reservados.add(exp);
                         
                     break;
                     case 6:// => 7
                         aux=conse.get(posicion+1);
                         conse.set(posicion," ");
                         conse.set(posicion+1," ");
                         ante.add(",");
                         ante.add(aux);
                     break;
                     case 7:// =>^
                         if("7".equals(conse.get(posicion+1))){
                             conse.set(posicion+2," ");
                         }
                         conse.set(posicion+1," ");
                         conse.set(posicion," ");
                         if(exp.nega==1){
                             exp.conse.set(posicion-2," ");
                         }
                         exp.conse.set(posicion-1," ");
                         exp.conse.set(posicion," ");
                         reservados.add(exp);
                     break;
                     case 8:// => v
                         conse.set(posicion, ",");
                     break;
                     case 9:// => ->
                         conse.set(posicion," ");
                         conse.add(",");
                         if(nega==1){
                             ante.add(conse.get(posicion-2));
                             conse.set(posicion-2," ");
                         }
                         ante.add(",");
                         ante.add(conse.get(posicion-1));
                         conse.set(posicion-1," ");
                     break;
                     case 10://=> <=>
                         conse.set(posicion," ");
                         conse.add(",");
                         if(nega==1){
                             ante.add(conse.get(posicion-2));
                             conse.set(posicion-2," ");
                         }
                         ante.add(conse.get(posicion-1));
                         conse.set(posicion-1," ");
                         
                         exp.conse.set(posicion," ");
                         exp.ante.add(exp.conse.get(posicion+1));
                         if("7".equals(exp.conse.get(exp.posicion+1))){
                             exp.ante.add(exp.conse.get(posicion+2));
                             exp.conse.set(exp.posicion+2," ");
                         }
                         exp.conse.set(exp.posicion+1," ");
                         reservados.add(exp);
                     break;                         
                     default:
                         reservados=null;
                     break;
                }//cierra switch
        return reservados;
    }
    
    public String imprimeExp (){
        String reglaimp[] = {" ⇒","7 ⇒","∧ ⇒","∨ ⇒","→ ⇒","⇔ ⇒","⇒ 7","⇒ ∧","⇒ ∨","⇒ →","⇒ ⇔"};
        String antecedente="",consecuente="",imp="";
        for(int i=0;i<ante.size();i++)antecedente+=ante.get(i);
        for(int i=0;i<conse.size();i++)consecuente+=conse.get(i);
        
        if(renglon==1)
        imp="   "+renglon+"\t  \t⇒"+antecedente+"→"+consecuente+"\n";
        else
        imp=renglonPadre+"si"+renglon+"\t"+reglaimp[regla]+"\t "+antecedente+"⇒"+consecuente+"\n";
        System.out.print(imp);
        return imp;
    }

}
